<template>
  <div class="admin-user">
    <Row class="margin-top-10">
      <p class="find" style="margin-bottom: 20px;">
        <b class="admin-user__title">角色路由管理</b>
        <Select
          v-model="role"
          placeholder="选择角色"
          clearable
          style="width: 200px; margin-left: 20px; margin-right: 20px"
        >
          <Option v-for="item in allRoles" :key="item.id" :value="item.id">{{ item.name }}</Option>
        </Select>
        <Button class="admin-user__btn" type="primary" icon="md-search" @click="findData">查询</Button>
        <Button class="admin-user__btn" type="primary" icon="md-add" @click="handleAdd">添加</Button>
      </p>
      <Table :columns="columns" :data="datas" :loading="loading" @on-sort-change="handleSort"></Table>
      <Page
        class="pager"
        v-if="total > 0"
        :total="total"
        show-total
        show-elevator
        show-sizer
        :page-size="limit"
        @on-change="handlePageChange"
        @on-page-size-change="handlePageSizeChange"
      />
      <!-- 新增修改弹窗 -->
      <Modal
        class="common-dialog"
        v-model="showModal"
        :title="modalTitle"
        :loading="modalLoading"
        width="600"
        :mask-closable="false"
      >
        <Form ref="modalForm" :model="modalData" :rules="modalRule" :label-width="100">
          <FormItem prop="role" label="角色" :error="modalError.role">
            <Select v-model="modalData.role" placeholder="请选择角色" clearable>
              <Option v-for="item in allRoles" :key="item.id" :value="+item.id">{{ item.name }}</Option>
            </Select>
          </FormItem>
          <FormItem prop="routers" label="路由" :error="modalError.routers">
            <div class="common-dialog__tree">
              <Tree :data="modalTreeData" show-checkbox @on-check-change="handleTreeSelect"></Tree>
            </div>
          </FormItem>
        </Form>
        <div slot="footer">
          <Button type="text" @click="handleModalCancel">取消</Button>
          <Button type="primary" @click="handleModalConfrim">确认</Button>
        </div>
      </Modal>
    </Row>
  </div>
</template>

<script>
import http from "@/utils/http";
import { formatTimeToDDHHMMSS } from "@/utils/format-time";
import moment from "moment";
import { mapState } from "vuex";
// 其他
import AvatarSelector from "@/components/avatar-selector";
import ImagePreview from "@/components/uploader/components/ImagePreview";
// 模块名称
const NAME = "角色路由";
const MODULE = "access-route";
const RULE = {
  role: [{ required: true, message: "请选择角色" }],
  routers: [{ required: true, message: "请选择角色可以访问的路由" }]
};
// 默认数据
const DEFAULT_DATA = {
  role: "",
  routers: []
};

export default {
  name: MODULE,

  components: {
    [AvatarSelector.name]: AvatarSelector,
    [ImagePreview.name]: ImagePreview
  },

  data() {
    return {
      loading: true,
      role: "",
      sort: "createdAd_DESC",
      datas: [],
      total: 0,
      page: 1,
      limit: 10,
      columns: [
        {
          title: "序号",
          key: "index",
          width: 80,
          align: "center"
        },
        {
          title: "角色",
          key: "role",
          align: "center",
          render: (h, params) => {
            return h("span", params.row.role.name);
          }
        },
        {
          title: "可访问路由",
          key: 'routers',
          align: "left",
          render: (h, params) => {
            return h("span", params.row.routers.join('、') || '-');
          }
        },
        {
          title: "更新时间",
          align: "center",
          key: "updatedAt",
          sortable: "custom",
          render: (h, params) => {
            return (
              <span>
                {moment(params.row.updatedAt).format("YYYY/MM/DD HH:MM:SS")}
              </span>
            );
          }
        },
        {
          title: "创建时间",
          align: "center",
          key: "createdAt",
          sortable: "custom",
          render: (h, params) => {
            return (
              <span>
                {moment(params.row.createdAt).format("YYYY/MM/DD HH:MM:SS")}
              </span>
            );
          }
        },
        {
          title: "操作",
          align: "center",
          width: 200,
          key: "handle",
          render: (h, params) => {
            return (
              <div>
                <Button
                  type="primary"
                  size="small"
                  class="text-red"
                  onClick={() => this.handleUpdate(params.row)}
                >
                  修改
                </Button>
                <Button
                  type="error"
                  size="small"
                  class="text-red"
                  onClick={() => this.handleDelete(params.row)}
                >
                  删除
                </Button>
              </div>
            );
          }
        }
      ],
      showModal: false, // 控制modal的显隐
      modalLoading: false, // 点击modal确定按钮是否显示loading
      modalTitle: "", // modal标题
      isAddOrUpdate: "", // 是新增弹窗或者更新弹窗
      currentId: "", // 当前正在修改的商品Id
      modalData: { ...DEFAULT_DATA },
      modalRule: RULE,
      modalError: {},
      modalTreeData: []
    };
  },

  computed: {
    ...mapState({
      allRoles: state => state.role.list
    })
  },

  methods: {
    // 获取数据
    getData(init = true) {
      if (init) this.page = 1;
      this.loading = true;
      http({
        method: "GET",
        url: `/api/admin/${MODULE}`,
        params: {
          page: init ? 1 : this.page,
          limit: this.limit,
          role: this.role,
          sort: this.sort
        },
        operation: `获取${NAME}`
      }).then(res => {
        this.loading = false;
        if (res.data && res.ok) {
          this.datas = res.data.list.map((item, index) => {
            item.index = (this.page - 1) * this.limit + index + 1;
            return item;
          });
          this.total = res.data.total;
        }
      });
    },
    // 查找数据
    findData() {
      this.limit = 10;
      this.page = 1;
      this.total = 0;
      this.getData();
    },
    // 处理排序
    handleSort({ column, key, order }) {
      this.sort = [key, order.toString().toUpperCase()].join("_");
      this.getData();
    },
    // 生成树的渲染数据
    generateTreeData(curRoutes= []) {
      return this.$consts.SIDEBAR_MENUS.map(menu => {
        menu.children = menu.children || [];
        const oneItemMatch = menu.children.length === 0 && curRoutes.indexOf(menu.title) > -1;
        const allItemMatch = menu.children.length > 0 && menu.children.every(item => curRoutes.indexOf(item.title) > -1);
        return {
          title: menu.title,
          name: menu.name,
          expand: false,
          checked: oneItemMatch || allItemMatch,
          ...(oneItemMatch ? null : {
            children: menu.children.map(item => {
              return  {
                title: item.title,
                name: item.name,
                checked: curRoutes.indexOf(item.title) > -1
              }
            })
          })
        };
      });
    },
    // 打开新增弹窗
    handleAdd() {
      this.modalData = { ...DEFAULT_DATA };
      this.showModal = true;
      this.modalTitle = `新增${NAME}`;
      this.isAddOrUpdate = "add";
      this.modalTreeData = this.generateTreeData();
    },
    // 打开修改弹窗
    handleUpdate(item) {
      this.modalData.role = item.role.id;
      this.modalData.routers = item.routers;
      this.showModal = true;
      this.modalTitle = `修改${NAME}`;
      this.isAddOrUpdate = "update";
      this.currentId = item.id;
      this.modalTreeData = this.generateTreeData(item.routers);
    },
    // 监听树的选择事件
    handleTreeSelect(checked, current) {
      const routers = [];
      checked.forEach(item => {
        if (item.children instanceof Array) {
          if (item.children.length === 0) {
             routers.push(item.title);
          } else {
            item.children.forEach(child => {
              if (child.title) {
                routers.push(child.title);
              }
            });
          }
        } else {
          routers.push(item.title);
        }
      });
      this.modalData.routers = routers;
    },
    // 删除数据
    handleDelete(item) {
      this.$Modal.confirm({
        title: "温馨提示",
        content: `确定要删除此${NAME}？`,
        onOk: () => {
          http({
            method: "DELETE",
            url: `/api/admin/${MODULE}/${item.id}`,
            operation: `删除${NAME}`
          }).then(res => {
            if (res.data && res.ok) {
              // 更新datas
              this.showModal = false;
              this.$Message.success(`删除${NAME}成功`);
              this.getData();
            }
          });
        },
        onCancel: () => {}
      });
    },
    // 自定义校验
    selfValidator(data) {
      return true;
    },
    // 取消弹窗loading
    closeModalLoading() {
      this.modalLoading = false;
      // 避免校验完直接关闭弹窗
      this.$nextTick(() => {
        this.modalLoading = true;
        this.showModal = true;
      });
    },
    handleModalConfrim() {
      // 合法性校验
      this.$refs["modalForm"].validate(valid => {
        if (valid) {
          if (this.selfValidator(this.modalData)) {
            // 如果全部校验通过，发送POST请求
            if (this.isAddOrUpdate === "add") {
              this.modalLoading = true;
              http({
                method: "POST",
                url: `/api/admin/${MODULE}`,
                data: this.modalData,
                operation: `新增${NAME}`
              })
                .then(res => {
                  this.modalLoading = false;
                  if (res.data && res.ok) {
                    this.showModal = false;
                    this.$Message.success(`新增${NAME}成功`);
                    this.$refs["modalForm"].resetFields();
                    this.getData(true);
                  } else if (res.msg === "validate-error") {
                    Object.keys(res.data).forEach(key => {
                      const randomSpace = Array(parseInt(Math.random() * 20))
                        .fill(" ")
                        .join("");
                      this.modalError[key] = res.data[key] + randomSpace;
                    });
                  }
                })
                .catch(err => {
                  this.modalLoading = false;
                  this.$Message.error(`新增${NAME}失败, ${err.toString}`);
                });
            } else if (this.isAddOrUpdate === "update") {
              this.modalLoading = true;
              http({
                method: "PUT",
                url: `/api/admin/${MODULE}/${this.currentId}`,
                data: this.modalData,
                operation: `修改${NAME}`
              })
                .then(res => {
                  this.modalLoading = false;
                  if (res.data && res.ok) {
                    this.showModal = false;
                    this.$Message.success(`修改${NAME}成功`);
                    this.$refs["modalForm"].resetFields();
                    this.getData(true);
                  } else if (res.msg === "validate-error") {
                    Object.keys(res.data).forEach(key => {
                      const randomSpace = Array(parseInt(Math.random() * 20))
                        .fill(" ")
                        .join("");
                      this.modalError[key] = res.data[key] + randomSpace;
                    });
                  }
                })
                .catch(err => {
                  this.modalLoading = false;
                  this.$Message.error(`新增${NAME}失败, ${err.toString}`);
                });
            }
          }
        }
      });
    },
    handleModalCancel() {
      this.$refs["modalForm"].resetFields();
      this.showModal = false;
    },
    // 点击分页
    handlePageChange(val) {
      this.page = val;
      this.getData(false);
    },
    handlePageSizeChange(size) {
      this.limit = size;
      this.getData(false);
    }
  },
  created() {
    this.getData();
    if (this.allRoles.length === 0) {
      this.$store.dispatch("role/FETCH_ALL_ROLE");
    }
  }
};
</script>

<style lang="scss">
.admin-user {
  &__title {
    font-size: 16px;
  }

  &__btn {
    margin-right: 10px;
  }

  &__input {
    display: inline-block;
    width: 200px;
    margin-left: 20px;
    margin-right: 20px;
  }

  &__input + &__input {
    margin-left: -10px;
  }

  .right {
    float: right;
  }

  .add-icon {
    float: right;
  }

  .overflow-text {
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .ivu-tooltip-inner {
    max-width: inherit;
  }

  .change-btn {
    margin-right: 15px;
  }

  .modal-container {
    width: 600px;
    position: absolute;
    left: 50%;
    top: 0;
    margin-left: -300px;
  }

  .pager {
    text-align: right;
    margin-top: 30px;
  }

  .book-img {
    width: 50px;
    height: 80px;
    float: left;
    margin-right: 10px;
  }

  .book-detail > p {
    text-align: left;
    padding-right: 10px;
  }
}

.common-dialog textarea.ivu-i-input {
  font-size: 12px !important;
}

.common-dialog .ivu-form-item {
  margin-bottom: 32px;
}

.common-dialog__tree {
  width: 100%;
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid #dcdee2;
  border-radius: 4px;
  padding: 0 10px;
}
</style>
